/*
 *    Copyright 2022 Huawei Technologies Co., Ltd.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package org.edgegallery.developer.controller.application.vm;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import java.util.List;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import javax.ws.rs.QueryParam;
import org.apache.servicecomb.provider.rest.common.RestSchema;
import org.edgegallery.developer.common.Consts;
import org.edgegallery.developer.model.application.vm.AntiAffinityGroup;
import org.edgegallery.developer.model.restful.ErrorRespDto;
import org.edgegallery.developer.service.application.vm.VMAppAntiAffinityGroupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RestSchema(schemaId = "VMAppAntiAffinityGroup")
@RequestMapping("/mec/developer/v2/applications")
@Api(tags = "VMAppAntiAffinityGroup")
@Validated
public class VMAppAntiAffinityGroupCtl {
    private static final String REGEX_UUID = "[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}";

    @Autowired
    private VMAppAntiAffinityGroupService vmAppAntiAffinityGroupService;

    /**
     * create an antiaffinitygroup .
     */
    @ApiOperation(value = "create an antiaffinitygroup.", response = AntiAffinityGroup.class)
    @ApiResponses(value = {
        @ApiResponse(code = 200, message = "OK", response = AntiAffinityGroup.class),
        @ApiResponse(code = 400, message = "Bad Request", response = ErrorRespDto.class)
    })
    @RequestMapping(value = "/{applicationId}/anti-affinity-groups", method = RequestMethod.POST,
        consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @PreAuthorize("hasRole('DEVELOPER_TENANT') || hasRole('DEVELOPER_ADMIN')")
    public ResponseEntity<AntiAffinityGroup> createAntiAffinityGroup(
        @Pattern(regexp = REGEX_UUID, message = "applicationId must be in UUID format")
        @ApiParam(value = "applicationId", required = true) @PathVariable("applicationId") String applicationId,
        @NotNull @ApiParam(value = "AntiAffinityGroup", required = true) @RequestBody
            AntiAffinityGroup antiaffinitygroup) {
        AntiAffinityGroup result = vmAppAntiAffinityGroupService
            .createAntiAffinityGroup(applicationId, antiaffinitygroup);
        return ResponseEntity.ok(result);
    }

    /**
     * get all antiaffinitygroups.
     */
    @ApiOperation(value = "get all antiaffinitygroups.", response = AntiAffinityGroup.class, responseContainer = "List")
    @ApiResponses(value = {
        @ApiResponse(code = 200, message = "OK", response = AntiAffinityGroup.class, responseContainer = "List"),
        @ApiResponse(code = 400, message = "Bad Request", response = ErrorRespDto.class)
    })
    @RequestMapping(value = "/{applicationId}/anti-affinity-groups", method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE)
    @PreAuthorize("hasRole('DEVELOPER_TENANT') || hasRole('DEVELOPER_ADMIN')")
    public ResponseEntity<List<AntiAffinityGroup>> getAllAntiAffinityGroups(
        @Pattern(regexp = REGEX_UUID, message = "applicationId must be in UUID format")
        @ApiParam(value = "applicationId", required = true) @PathVariable("applicationId") String applicationId,
        @ApiParam(value = "vmId", required = false) @Size(max = Consts.LENGTH_64) @QueryParam("vmId") String vmId) {
        return ResponseEntity.ok(vmAppAntiAffinityGroupService.getAllAntiAffinityGroups(applicationId, vmId));
    }

    /**
     * get an antiaffinitygroup.
     */
    @ApiOperation(value = "get an antiaffinitygroup.", response = AntiAffinityGroup.class)
    @ApiResponses(value = {
        @ApiResponse(code = 200, message = "OK", response = AntiAffinityGroup.class),
        @ApiResponse(code = 400, message = "Bad Request", response = ErrorRespDto.class)
    })
    @RequestMapping(value = "/{applicationId}/anti-affinity-groups/{antiaffinitygroupId}", method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE)
    @PreAuthorize("hasRole('DEVELOPER_TENANT') || hasRole('DEVELOPER_ADMIN')")
    public ResponseEntity<AntiAffinityGroup> getAntiAffinityGroup(
        @Pattern(regexp = REGEX_UUID, message = "applicationId must be in UUID format")
        @ApiParam(value = "applicationId", required = true) @PathVariable("applicationId") String applicationId,
        @ApiParam(value = "antiaffinitygroupId", required = true) @PathVariable("antiaffinitygroupId")
            String antiaffinitygroupId) {
        return ResponseEntity
            .ok(vmAppAntiAffinityGroupService.getAntiAffinityGroup(applicationId, antiaffinitygroupId));
    }

    /**
     * modify an antiaffinitygroup.
     */
    @ApiOperation(value = "modify an antiaffinitygroup.", response = AntiAffinityGroup.class)
    @ApiResponses(value = {
        @ApiResponse(code = 200, message = "OK", response = AntiAffinityGroup.class),
        @ApiResponse(code = 400, message = "Bad Request", response = ErrorRespDto.class)
    })
    @RequestMapping(value = "/{applicationId}/anti-affinity-groups/{antiaffinitygroupId}", method = RequestMethod.PUT,
        consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @PreAuthorize("hasRole('DEVELOPER_TENANT') || hasRole('DEVELOPER_ADMIN')")
    public ResponseEntity<AntiAffinityGroup> modifyAntiAffinityGroup(
        @Pattern(regexp = REGEX_UUID, message = "applicationId must be in UUID format")
        @ApiParam(value = "applicationId", required = true) @PathVariable("applicationId") String applicationId,
        @ApiParam(value = "antiaffinitygroupId", required = true) @PathVariable("antiaffinitygroupId")
            String antiaffinitygroupId, @NotNull @ApiParam(value = "AntiAffinityGroup", required = true) @RequestBody
        AntiAffinityGroup antiaffinitygroup) {
        AntiAffinityGroup result = vmAppAntiAffinityGroupService
            .modifyAntiAffinityGroup(applicationId, antiaffinitygroupId, antiaffinitygroup);
        return ResponseEntity.ok(result);
    }

    /**
     * delete an antiaffinitygroup.
     */
    @ApiOperation(value = "delete an antiaffinitygroup.", response = Boolean.class)
    @ApiResponses(value = {
        @ApiResponse(code = 200, message = "OK", response = Boolean.class),
        @ApiResponse(code = 400, message = "Bad Request", response = ErrorRespDto.class)
    })
    @RequestMapping(value = "/{applicationId}/anti-affinity-groups/{antiaffinitygroupId}",
        method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
    @PreAuthorize("hasRole('DEVELOPER_TENANT') || hasRole('DEVELOPER_ADMIN')")
    public ResponseEntity<Boolean> deleteAntiAffinityGroup(
        @Pattern(regexp = REGEX_UUID, message = "applicationId must be in UUID format")
        @ApiParam(value = "applicationId", required = true) @PathVariable("applicationId") String applicationId,
        @ApiParam(value = "antiaffinitygroupId", required = true) @PathVariable("antiaffinitygroupId")
            String antiaffinitygroupId) {
        Boolean result = vmAppAntiAffinityGroupService.deleteAntiAffinityGroup(applicationId, antiaffinitygroupId);
        return ResponseEntity.ok(result);
    }

}
